#ifndef LIGHT_H
#define LIGHT_H

#include "stdafx.h"
#include "RenderResource.h"
enum DecoLightType
{
	LT_PointLight,
	LT_DirectionLight,
	LT_SpotLight
};

enum DecoLightAttenuationType
{
	AT_Const,
	AT_Linear,
	AT_Quadratic,
	AT_Spot,
	AT_Max
};

const INT MAX_LIGHT = 4;
class DecoLight {
private:
	vector3 m_position;
	DecoColor m_specular;
	DecoColor m_diffuse;
	DecoLightType m_type;
	FLOAT m_spotCutAngle;
	vector3 m_spotDirection;
	FLOAT m_attenutionFactor[AT_Max];

public:
	/* construction function */
	DecoLight() : m_position(vector3(0, 0, 0)), m_specular(DecoColor(0x00000000)), m_diffuse(DecoColor(0x00000000)), m_type(LT_DirectionLight),
		m_spotCutAngle(0), m_spotDirection(vector3(0, 0, 0))
	{
		memset(m_attenutionFactor, 0, 4 * sizeof(FLOAT));
		m_attenutionFactor[0] = 1;
	}
	DecoLight(DecoLightType type) : m_position(vector3(0, 0, 0)), m_specular(DecoColor(0x00000000)), m_diffuse(DecoColor(0x00000000)), m_type(type),
									m_spotCutAngle(0), m_spotDirection(vector3(0, 0, 0))
	{
		memset(m_attenutionFactor, 0, 4 * sizeof(FLOAT));
		m_attenutionFactor[0] = 1;
	}
	DecoLight(vector3 pos, const DecoColor& diffuse, const DecoColor& specular, DecoLightType type, FLOAT spotCutAngle = 0, vector3 spotDirection = vector3(0, 0, 0))
																								: m_position(pos),
																								  m_type(type),
																								  m_specular(specular),
																								  m_diffuse(diffuse),
																								  m_spotCutAngle(spotCutAngle),
																								  m_spotDirection(spotDirection)
	{
		memset(m_attenutionFactor, 0, 4 * sizeof(FLOAT));
		m_attenutionFactor[0] = 1;
	}
	DecoLightType GetType() const
	{
		return m_type;
	}
	void SetPosition (vector3 p)
	{
		m_position = p;
	}
	void GetPosition (FLOAT * pos) const;
	void GetSpecular(FLOAT* specular) const;
	void GetDiffuse(FLOAT* diffuse) const;
	vector3 GetPosition() const;
	vector3 GetSpecular() const;
	vector3 GetDiffuse() const;

	BOOL IsInRange(const vector3& point) const;
	void SetSpotCutoffAngle(FLOAT angle)
	{
		assert(m_type == LT_SpotLight);
		m_spotCutAngle = angle;
	}
	FLOAT GetSpotCutoffAngle() const
	{
		assert(m_type == LT_SpotLight);
		return m_spotCutAngle;
	}
	void SetSpotDirection(const vector3& dir)
	{
		assert(m_type == LT_SpotLight);
		m_spotDirection = dir;
	}
	void GetSpotDirection(FLOAT* dir) const;
	void SetLightAttenuation(DecoLightAttenuationType type, FLOAT factor)
	{
		m_attenutionFactor[static_cast<INT>(type)] = factor;
	}
	FLOAT GetLightAttenuation(DecoLightAttenuationType type) const
	{
		return m_attenutionFactor[static_cast<INT>(type)];
	}
	friend DecoArchive& operator<< (DecoArchive& Ar, const DecoLight& light);
	friend DecoArchive& operator>> (DecoArchive& Ar, DecoLight& light);
};


#endif
